from flask import current_app, jsonify
from flask import g
from flask import render_template
from flask import request
from flask import session

from info import db
from info.models import News, Comment, User
from info.modules.news import news_blu
from info.utils.common import login_user_info
from info.utils.response_code import RET

###关注
# 请求路径: /news/followed_user
# 请求方式: POST
# 请求参数:user_id,action
# 返回值: errno, errmsg
"""
1.判断用户是否登陆
2.获取参数
3.校验参数,并且校验操作方式
4.根据id查询作者,并判断作者是否存在
5.执行关注/取消的操作
6.返回响应
"""


@news_blu.route('/followed_user', methods=['POST'])
@login_user_info
def followed_user():
    # 1.判断用户是否登陆
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    # 2.获取参数
    author_id = request.json.get('user_id')
    action = request.json.get('action')
    # 3.校验参数,并且校验操作方式
    if not all([author_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    if action not in ['follow', 'unfollow']:
        return jsonify(errno=RET.PARAMERR, errmsg='参数不合法')
    # 4.根据id查询作者,并判断作者是否存在
    try:
        author = User.query.get(author_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询失败')
    if not author:
        return jsonify(errno=RET.NODATA, errmsg='作者不存在')
    # 5.执行关注/取消的操作
    try:
        if action == 'follow':
            author.followers.append(g.user)
        else:
            author.followers.remove(g.user)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='操作失败')
    # 6.返回响应
    return jsonify(errno=RET.OK, errmsg='操作成功')




###评论与回复评论
# 请求路径: /news/news_comment
# 请求方式: POST
# 请求参数:news_id,comment,parent_id
# 返回值: errno,errmsg,评论字典
@news_blu.route('/news_comment', methods=['POST'])
@login_user_info
def news_comment():
    # 1.判断用户是否登陆状态
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    # 2.获取参数
    news_id = request.json.get('news_id')
    content = request.json.get('comment')
    parent_id = request.json.get('parent_id')
    # 3.校验,为空校验(有可能没有父评论)
    if not all([news_id, content]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    # 4.根据编号取出新闻对象,并判断是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据获取失败')
    if not news:
        return jsonify(errno=RET.NODATA, errmsg='该条新闻不存在')
    # 5.创建评论对象,设置评论对象属性
    comment = Comment()
    comment.news_id = news.id
    comment.user_id = g.user.id
    comment.content = content
    if parent_id:
        comment.parent_id = parent_id
    # 6.添加评论对象到数据库
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='添加失败')
    # 7.返回响应
    return jsonify(errno=RET.OK, errmsg='评论成功', data=comment.to_dict())


###收藏功能添加
# 请求路径: /news/news_collect
# 请求方式: POST
# 请求参数:news_id,action, g.user
# 返回值: errno,errmsg
@news_blu.route('/news_collect', methods=['POST'])
@login_user_info
def news_collect():
    # 1.获取参数news_id,action, g.user
    news_id = request.json.get('news_id')
    action = request.json.get('action')
    # 2.校验非空,操作类型校验
    if not all([news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    if not action in ["collect", "cancel_collect"]:
        return jsonify(errno=RET.DATAERR, errmsg='参数类型错误')
    # 3.获取新闻对象,查看新闻对象是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取对象失败')

    if not news:
        return jsonify(errno=RET.NODATA, errmsg='该条新闻不存在')
    # 4.判断是收藏/取消收藏,添加新闻对象到收藏列表
    try:
        if action == "collect":
            g.user.collection_news.append(news)
        else:
            g.user.collection_news.remove(news)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='操作失败')
    # 7.返回响应
    return jsonify(errno=RET.OK, errmsg='操作成功')


@news_blu.route('/<int:news_id>')
@login_user_info
def get_news_detail(news_id):
    # 用户详情页面
    """
    1.通过session获取到当前用户信息
    2.判断当前是否有用户登陆
    """

    new = News.query.get(news_id)
    new.clicks += 1
    # 排行榜
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(10)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据获取失败')

    click_news_list = []
    for news in news_list if news_list else []:
        click_news_list.append(news.to_dict())

    # 获取当前新闻的所有评论
    try:
        comments = Comment.query.filter(Comment.news_id == new.id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据查询失败')

    # 生成评论列表
    comment_list = []
    for comment in comments:
        comment_list.append(comment.to_dict())

    # 判断用户是否已经收藏该新闻
    is_collect = False
    if g.user and new in g.user.collection_news:
        is_collect = True

    is_followers = False
    if g.user and new.user in g.user.followed:
        is_followers = True

    data = {
        "user_info": g.user.to_dict() if g.user else "",
        'click_news_list': click_news_list,
        "new_info": new.to_dict(),
        "is_collect": is_collect,
        'comments': comment_list,
        'is_followers': is_followers
    }

    return render_template('news/detail.html', data=data)
